package com.gzhryc.shared_device.oem.h5.agent.controllers.api.v1.cdcz;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.IDTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.api.DefaultAPIResponse;
import com.gzhryc.servlet.DtoConstants;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.cdcz.code.dao.db.ChargeSocket;
import com.gzhryc.shared_device.cdcz.code.dao.db.ChargeSocketSlot;
import com.gzhryc.shared_device.cdcz.code.dao.enums.ChargeSocketEnum;
import com.gzhryc.shared_device.cdcz.code.dao.enums.ChargeSocketSlotEnum;
import com.gzhryc.shared_device.cdcz.code.services.ChargeSocketService;
import com.gzhryc.shared_device.cdcz.code.services.ChargeSocketSlotService;
import com.gzhryc.shared_device.cdcz.code.services.dto.ChargeSocketSearch;
import com.gzhryc.shared_device.cdcz.core.ICDCZNetworkService;
import com.gzhryc.shared_device.cdcz.core.enums.ECDCZCostMode;
import com.gzhryc.shared_device.cdcz.core.models.CDCZChargeCommand;
import com.gzhryc.shared_device.cdcz.core.models.CDCZExecuteResult;
import com.gzhryc.shared_device.common.device.dao.db.Device;
import com.gzhryc.shared_device.common.device.services.DeviceService;
import com.gzhryc.shared_device.oem.code.HttpNetworkServiceUtils;
import com.gzhryc.shared_device.oem.code.agent.dao.db.AgentRelationDevice;
import com.gzhryc.shared_device.oem.code.agent.services.AgentRelationDeviceService;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.device.dao.models.AgentRelationCDCZDevice;
import com.gzhryc.shared_device.oem.code.device.services.AgentRelationCDCZDeviceService;
import com.gzhryc.shared_device.oem.code.device.services.dto.AgentRelationCDCZDeviceSearch;
import com.gzhryc.shared_device.oem.code.user.ERoleType;
import com.gzhryc.shared_device.oem.h5.agent.ClientAPICodeConstants;
import com.gzhryc.shared_device.oem.h5.agent.LoginUser;
import com.gzhryc.shared_device.oem.h5.agent.WebConstants;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.cdcz.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

public class CDCZDeviceController {

    @Route(value = "/agent/api/v1/cdcz/device/count.data")
    public CDCZDeviceCountResponse deviceCount(HttpServletRequest request){
        CDCZDeviceCountResponse apiResp = new CDCZDeviceCountResponse(ClientAPICodeConstants.NULL_DATA, "暂无数据");
        LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
        if (loginUser != null) {
            if(ERoleType.Agent.index().equals(loginUser.getRoleType())) {
                ChargeSocketSearch search = new ChargeSocketSearch();
                search.setUserId(loginUser.getId());

                Long deviceCount = ChargeSocketService.self().countJoinBySearch(search);

                search.setDeploy(true);
                Long deployCount = ChargeSocketService.self().countJoinBySearch(search);

                search.setDeploy(null);
                search.setState(ChargeSocketEnum.State.Online.index());
                Long onlineCount = ChargeSocketService.self().countJoinBySearch(search);

                apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                apiResp.getBody().setDeviceFunCodeName(EDeviceFunCode.CDCZ.note());
                apiResp.getBody().setDeviceCount(deviceCount);
                apiResp.getBody().setDeployCount(deployCount);
                apiResp.getBody().setOnlineCount(onlineCount);
            }else{
                AgentRelationCDCZDeviceSearch search = new AgentRelationCDCZDeviceSearch();
                search.setUserId(loginUser.getParentId());
                search.setRelationUserId(loginUser.getId());

                Long deviceCount = AgentRelationCDCZDeviceService.self().countJoinBySearch(search);

                search.setDeploy(true);
                Long deployCount = AgentRelationCDCZDeviceService.self().countJoinBySearch(search);

                search.setDeploy(null);
                search.setState(ChargeSocketEnum.State.Online.index());
                Long onlineCount = AgentRelationCDCZDeviceService.self().countJoinBySearch(search);

                apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                apiResp.getBody().setDeviceFunCodeName(EDeviceFunCode.CDCZ.note());
                apiResp.getBody().setDeviceCount(deviceCount);
                apiResp.getBody().setDeployCount(deployCount);
                apiResp.getBody().setOnlineCount(onlineCount);
            }
        }
        return apiResp;
    }

    @Route(value = "/agent/api/v1/cdcz/device/list.data")
    public CDCZDeviceListResponse list(HttpServletRequest request) {
        CDCZDeviceListResponse apiResp = new CDCZDeviceListResponse(ClientAPICodeConstants.NULL_DATA, "暂无数据");
        CDCZDeviceListRequest apiReq = WebUtils.getJsonRequest(request, CDCZDeviceListRequest.class);
        if (apiReq != null) {
            Integer pageNo = apiReq.getBody().getPageNo() == null ? 1 : apiReq.getBody().getPageNo();
            Integer deployState = apiReq.getBody().getDeployState() == null ? 0 : apiReq.getBody().getDeployState();
            LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
            if (loginUser != null) {
                List<ChargeSocket> chargeSocketList = null;
                if(ERoleType.Agent.index().equals(loginUser.getRoleType())) {
                    ChargeSocketSearch search = new ChargeSocketSearch();
                    search.setUserId(loginUser.getId());
                    if(apiReq.getBody().getState() != null && apiReq.getBody().getState() > 0) {
                        search.setState(apiReq.getBody().getState());
                    }
                    search.setTrim(apiReq.getBody().getTrim());
                    if (deployState == 1) {
                        search.setDeploy(false);
                    } else if (deployState == 2) {
                        search.setDeploy(true);
                    }
                    chargeSocketList = ChargeSocketService.self().findJoinBySearch(search, pageNo, WebConstants.PAGE_LIMIT);
                }else{
                    AgentRelationCDCZDeviceSearch search = new AgentRelationCDCZDeviceSearch();
                    search.setUserId(loginUser.getParentId());
                    if(apiReq.getBody().getState() != null && apiReq.getBody().getState() > 0) {
                        search.setState(apiReq.getBody().getState());
                    }
                    search.setRelationUserId(loginUser.getId());
                    search.setTrim(apiReq.getBody().getTrim());
                    if (deployState == 1) {
                        search.setDeploy(false);
                    } else if (deployState == 2) {
                        search.setDeploy(true);
                    }
                    List<AgentRelationCDCZDevice> data = AgentRelationCDCZDeviceService.self().findJoinBySearch(search,pageNo, WebConstants.PAGE_LIMIT);
                    if(data != null && data.size() > 0){
                        chargeSocketList = new ArrayList<>();
                        for(AgentRelationCDCZDevice item : data){
                            chargeSocketList.add(item);
                        }
                    }
                }

                if (chargeSocketList != null && chargeSocketList.size() > 0) {
                    apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                    apiResp.getBody().setItems(new ArrayList<>());

                    List<String> deviceSnList = new ArrayList<>();
                    for (ChargeSocket chargeSocket : chargeSocketList) {
                        deviceSnList.add(chargeSocket.getDeviceSn());
                    }

                    List<ChargeSocketSlot> chargeSocketSlotList = ChargeSocketSlotService.self().findByDeviceSn(deviceSnList);
                    for (ChargeSocket chargeSocket: chargeSocketList) {
                        CDCZDeviceListResponse.DeviceItem item = ClassTools.copy(new CDCZDeviceListResponse.DeviceItem(), chargeSocket);
                        item.setStateName(chargeSocket.getStateName());
                        item.setPlaceId(chargeSocket.getDevice().getPlaceId());
                        item.setPlaceName(chargeSocket.getDevice().getPlaceName());
                        item.setPlaceAreaName(chargeSocket.getDevice().getAreaName());

                        Integer workSlotCount = 0;
                        if(chargeSocketSlotList != null && chargeSocketSlotList.size() > 0){
                            for(ChargeSocketSlot slot : chargeSocketSlotList){
                                if(chargeSocket.getDeviceSn().equals(slot.getDeviceSn()) && ChargeSocketSlotEnum.State.Working.index().equals(slot.getState())){
                                    workSlotCount = workSlotCount + 1;
                                }
                            }
                        }
                        item.setWorkSlotCount(workSlotCount);
                        apiResp.getBody().getItems().add(item);
                    }
                }
            }
        }
        return apiResp;
    }

    @Route(value = "/agent/api/v1/cdcz/device/info.data")
    public CDCZDeviceInfoResponse info(HttpServletRequest request) {
        CDCZDeviceInfoResponse apiResp = new CDCZDeviceInfoResponse(ClientAPICodeConstants.NULL_DATA, "暂无数据");
        CDCZDeviceInfoRequest apiReq = WebUtils.getJsonRequest(request, CDCZDeviceInfoRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn())) {
            LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
            if (loginUser != null) {
                Device device = DeviceService.self().getByDeviceSn(apiReq.getBody().getDeviceSn());
                if (device != null) {
                    if (device.getUserId() == null) {
                        apiResp.setCode(ClientAPICodeConstants.NOT_POWER, "无权限查看");
                        return apiResp;
                    }else if(ERoleType.Agent.index().equals(loginUser.getRoleType())){
                         if(!device.getUserId().equals(loginUser.getId())){
                             apiResp.setCode(ClientAPICodeConstants.NOT_POWER, "无权限查看");
                             return apiResp;
                         }
                    }else {
                        AgentRelationDevice agentRelationDevice = AgentRelationDeviceService.self().getByKeys(loginUser.getParentId(),loginUser.getId(),device.getDeviceSn());
                        if(agentRelationDevice == null){
                            apiResp.setCode(ClientAPICodeConstants.NOT_POWER, "无权限查看");
                            return apiResp;
                        }
                    }

                    ChargeSocket chargeSocket = ChargeSocketService.self().getByDeviceSn(device.getDeviceSn());
                    if (chargeSocket != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        ClassTools.copy(apiResp.getBody(), chargeSocket);

                        apiResp.getBody().setPlaceId(device.getPlaceId());
                        apiResp.getBody().setPlaceName(device.getPlaceName());

                        List<ChargeSocketSlot> slotList = ChargeSocketSlotService.self().findByDeviceSn(chargeSocket.getDeviceSn());
                        if (slotList != null && slotList.size() > 0) {
                            apiResp.getBody().setSlotItems(new ArrayList<>());
                            for (ChargeSocketSlot slot : slotList) {
                                CDCZDeviceInfoResponse.SlotItem item = ClassTools.copy(new CDCZDeviceInfoResponse.SlotItem(), slot);
                                item.setOverloadStateName(slot.getOverloadStateName());
                                item.setPowerStateName(slot.getPowerStateName());
                                item.setTemperatureStateName(slot.getTemperatureStateName());
                                item.setStateName(slot.getStateName());
                                apiResp.getBody().getSlotItems().add(item);
                            }
                        }
                    }
                }
            }
        }
        return apiResp;
    }

    @Route(value = "/agent/api/v1/cdcz/device/operate/charge.do")
    public DefaultAPIResponse charge(HttpServletRequest request) {
        DefaultAPIResponse apiResp = new DefaultAPIResponse(ClientAPICodeConstants.EXECUTE_ERROR, "充电测试失败");
        CDCZOperateChargeTestRequest apiReq = WebUtils.getJsonRequest(request, CDCZOperateChargeTestRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn()) && apiReq.getBody().getSlotNum() != null) {
            Integer chargeTimes = apiReq.getBody().getChargeTimes() == null ? 10 : apiReq.getBody().getChargeTimes();
            ChargeSocket chargeSocket = ChargeSocketService.self().getByDeviceSn(apiReq.getBody().getDeviceSn());
            if (chargeSocket != null) {
                ICDCZNetworkService networkService = HttpNetworkServiceUtils.getCDCZNetworkService(chargeSocket.getIotNodeId());
                if (networkService != null) {
                    String tradeNo = "TEST" + IDTools.getTimestampSecondID();

                    String msgId = IDTools.getTimestampNanoID();
                    CDCZChargeCommand chargeCommand = new CDCZChargeCommand();
                    chargeCommand.setMessageId(msgId);
                    chargeCommand.setDeviceSn(apiReq.getBody().getDeviceSn());
                    chargeCommand.setCostMode(ECDCZCostMode.TimeSetMeal.index());
                    chargeCommand.setSlotNum(apiReq.getBody().getSlotNum());
                    chargeCommand.setTradeNo(tradeNo);
                    chargeCommand.setChargeTimes(chargeTimes);
                    chargeCommand.setChargeElectricity(5.0);    //默认测试5度电

                    CDCZExecuteResult executeResult = networkService.charge(chargeCommand);
                    if (executeResult != null) {
                        if (CDCZExecuteResult.SUCCESS.equals(executeResult.getCode())) {
                            apiResp.setCode(DtoConstants.SUCCESS, null);
                            ChargeSocketSlotService.self().freeToWorking(chargeCommand.getDeviceSn(), chargeCommand.getSlotNum(), tradeNo);
                        } else if (StringTools.isNotBlank(executeResult.getMsg())) {
                            apiResp.setMsg(executeResult.getMsg());
                        } else {
                            apiResp.setMsg("发送命令失败");
                        }
                    } else {
                        apiResp.setMsg("充电插座网络服务无响应");
                    }
                } else {
                    apiResp.setMsg("未获取充电插座网络服务");
                }
            }
        }
        return apiResp;
    }
}
